package com.zackeus.xupdate;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;

import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;

import com.zackeus.common.utils.ConvertUtils;
import com.zackeus.common.utils.ObjectUtils;
import com.zackeus.common.utils.Utils;
import com.zackeus.xupdate.listener.OnFileDownloadListener;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @name: XUpdateService
 * @author: zz
 * @date: 2022/12/12
 */
public class XUpdateService extends Service {

    private static final int DOWNLOAD_NOTIFY_ID = 200;
    private static final String DOWNLOAD_PROGRESS_CHANNEL = "DOWNLOAD-PROGRESS";

    private NotificationManagerCompat mNotificationManager;

    @Override
    public void onCreate() {
        super.onCreate();

        /* NotificationManagerCompat 向下兼容 */
        this.mNotificationManager = NotificationManagerCompat.from(XUpdateService.this);
        /* 创建 channel */
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (mNotificationManager.getNotificationChannel(DOWNLOAD_PROGRESS_CHANNEL) == null) {
                NotificationChannel channel = new NotificationChannel(DOWNLOAD_PROGRESS_CHANNEL, "下载进度通知", NotificationManager.IMPORTANCE_HIGH);
                channel.setDescription("下载进度通知");
                /* 禁用锁屏通知 */
                channel.setLockscreenVisibility(NotificationCompat.VISIBILITY_SECRET);
                mNotificationManager.createNotificationChannel(channel);
            }
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new XUpdateBinder();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        this.mNotificationManager.cancel(DOWNLOAD_NOTIFY_ID);
        this.mNotificationManager = null;
        super.onDestroy();
    }

    public class XUpdateBinder extends Binder implements OnFileDownloadListener {

        private NotificationCompat.Builder mBuilder;
        private int mOldRate = 0;

        @Override
        public void onStart() {
            /* 清空通知栏状态 */
            XUpdateService.this.mNotificationManager.cancel(DOWNLOAD_NOTIFY_ID);

            mBuilder = new NotificationCompat.Builder(XUpdateService.this, DOWNLOAD_PROGRESS_CHANNEL)
                    .setContentTitle(getString(R.string.xupdate_start_download))
                    .setContentText(getString(R.string.xupdate_connecting_service))
                    .setSmallIcon(R.drawable.xupdate_icon_app_update)
                    .setLargeIcon(ConvertUtils.drawable2Bitmap(Utils.getAppIcon()))
                    .setOngoing(Boolean.TRUE)
                    .setAutoCancel(Boolean.FALSE)
                    .setWhen(System.currentTimeMillis());
            mNotificationManager.notify(DOWNLOAD_NOTIFY_ID, mBuilder.build());
        }

        @Override
        public void onProgress(long progress, long total) {
            if (ObjectUtils.isNull(mBuilder))
                return;

            int rate = 0;
            if (total != 0) {
                BigDecimal p = new BigDecimal(progress);
                BigDecimal t = new BigDecimal(total);
                rate = p.multiply(new BigDecimal(100)).divide(t, RoundingMode.HALF_UP).intValue();
            }

            /* 限制单个应用通知队列频率 */
            /* notify方法会将Notification加入系统的通知队列，当前应用发出的Notification数量超过50时，不再继续向系统的通知队列添加Notification，即造成了notificationManagerCompat.notify(TAG, NOTIFY_ID, notify)无效的现象 */
            if (Math.abs(rate - mOldRate) >= 4) {
                this.mBuilder.setContentTitle(getString(R.string.xupdate_lab_downloading) + Utils.getAppName())
                        .setContentText(rate + "%")
                        .setProgress(100, rate, Boolean.FALSE)
                        .setWhen(System.currentTimeMillis());
                Notification notification = mBuilder.build();
                notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONLY_ALERT_ONCE;
                mNotificationManager.notify(DOWNLOAD_NOTIFY_ID, notification);
            }

            this.mOldRate = rate;
        }

        @Override
        public void onCompleted(File file) {
            XUpdateService.this.mNotificationManager.cancel(DOWNLOAD_NOTIFY_ID);
        }

        @Override
        public void onError(Throwable throwable) {
            XUpdateService.this.mNotificationManager.cancel(DOWNLOAD_NOTIFY_ID);
        }
    }
}
